/*
 *  The MIT License
 * 
 *  Copyright 2011 Specular Contributors.
 * 
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 * 
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 * 
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *  THE SOFTWARE.
 */
package org.specular.graphics;

/**
 * This class represents one graphics pixel. It can take values of alpha,
 * luminance and the standard RBB color scheme.
 * @author Joshua Mabrey
 */
public class Pixel {

    /**
     * Sets this pixels red, green blue and alpha values as specified. Note that
     * the int version of the constructor will convert to the internal
     * representation of a float. This requires extra calculation on object
     * creation making this constructor less desirable to use than the float
     * version. As such, this constructor is preferred. This constructor clamps
     * float values to between 0.0f and 1.0f.
     * @param argRed
     * @param argGreen
     * @param argBlue
     * @param argAlpha
     */
    public Pixel(float argRed, float argGreen, float argBlue, float argAlpha) {
        /* Check and clamp values, which is only necessary in this constructor
        because all other constructors eventually call this one, which
        performs the actual variable initialization.
         */

        if (argRed > 1.0f) {
            //the value is too large; lets shrink it
            argRed = 1.0f;
        } else if (argRed < 0.0f) {
            //the value is too small; lets set it to zero
            argRed = 0.0f;
        }
        this.red = argRed;

        if (argGreen > 1.0f) {
            //the value is too large; lets shrink it
            argGreen = 1.0f;
        } else if (argGreen < 0.0f) {
            //the value is too small; lets set it to zero
            argGreen = 0.0f;
        }
        this.green = argGreen;

        if (argBlue > 1.0f) {
            //the value is too large; lets shrink it
            argBlue = 1.0f;
        } else if (argBlue < 0.0f) {
            //the value is too small; lets set it to zero
            argBlue = 0.0f;
        }
        this.blue = argBlue;

        if (argAlpha > 1.0f) {
            //the value is too large; lets shrink it
            argAlpha = 1.0f;
        } else if (argAlpha < 0.0f) {
            //the value is too small; lets set it to zero
            argAlpha = 0.0f;
        }
        this.alpha = argAlpha;
    }

    /**
     * Sets this pixels red, green and blue values as specified, with
     * a default alpha value of 0.0f. Note that the int version of the
     * constructor will convert to the internal representation of a float.
     * This requires extra calculation on object creation making this
     * constructor less desirable to use than the float version. As such, this
     * constructor is preferred. This constructor clamps float values to
     * between 0.0f and 1.0f.
     * @param argRed
     * @param argGreen
     * @param argBlue
     */
    public Pixel(float argRed, float argGreen, float argBlue) {
        this(argRed,argGreen,argBlue,0.0f);
        //calls the full constructor with default 0.0f alpha value
    }

    /**
     * Sets this pixels red, green blue and alpha values as specified. Note that
     * the int version of the constructor will convert to the internal
     * representation of a float. This requires extra calculation on object
     * creation making this constructor less desirable to use than the float
     * version. However, for convenience, this constructor is provided. This
     * constructor clamps int values to between 0 and 255.
     * @param argRed
     * @param argGreen
     * @param argBlue
     * @param argAlpha
     */
    public Pixel(int argRed, int argGreen, int argBlue, int argAlpha) {
        /*We need to excerise extreme caution to avoid chopping of sig bits.
         * It isn't very readable, but this call converts the int values to
         * floats without losing percision.
         */
        this(((float)argRed)/((float)255),
                ((float)argGreen)/((float)255),
                ((float)argBlue)/((float)255),
                ((float)argAlpha)/((float)255));
    }

    /**
     * Sets this pixels red, green and blue values as specified, with
     * a default alpha value of 0. Note that the int version of the constructor
     * will convert to the internal representation of a float. This requires
     * extra calculation on object creation making this constructor
     * less desirable to use than the float version. However, for convenience,
     * this constructor is provided. This constructor clamps int values to
     * between 0 and 255.
     * @param argRed
     * @param argGreen
     * @param argBlue
     */
    public Pixel(int argRed, int argGreen, int argBlue) {
        this(argRed,argGreen,argBlue,0);
        //calls the other int constructor with a 0 alpha value
    }
    /**
     * Represents the red value of the pixel, with 1.0f being the full red
     * value, and 0.0f being the full absence of red.
     */
    private float red;
    /**
     * Represents the green value of the pixel, with 1.0f being the full green
     * value, and 0.0f being the full absence of green.
     */
    private float green;
    /**
     * Represents the blue value of the pixel, with 1.0f being the full blue
     * value, and 0.0f being the full absence of blue.
     */
    private float blue;
    /**
     * Represents the transparency of the pixel, with 1.0f being fully
     * transparent, and 0.0f being the full absence of transparency.
     */
    private float alpha;
}
